﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;

namespace AdornerTest
{

	/// <summary>
	/// This is a really rough connector type.  This would need to be significantly refactors
	/// to really work.  More than likely, each line would be an element on the canvas?
	/// </summary>
	public class PinAdorner : Adorner
	{

		private enum PinPlacement
		{
			Input,
			Output
		}

		Dictionary<PinPlacement, Thumb> _dicPins = null;

		// Adorner requires a UIElement constructor
		public PinAdorner(UIElement adornedElement)
		  : base(adornedElement)
		{
			Double thumbSize = 15;
			_children = new VisualCollection(this);
			_dicPins = new Dictionary<PinPlacement, Thumb>();
			CreateThumbs(thumbSize);
		}

		/// <summary>
		/// Create four corners and center handle
		/// </summary>
		/// <param name="thumbSize"></param>
		private void CreateThumbs(double thumbSize)
		{
			_dicPins.Add(PinPlacement.Input, CreateThumb(thumbSize, thumbSize, Brushes.Silver, Cursors.Pen, PinPlacement.Input));
			//_dicPins.Add(PinPlacement.Output, CreateThumb(thumbSize, thumbSize, Brushes.Silver, Cursors.Pen, PinPlacement.Output));
			_dicPins[PinPlacement.Input].DragDelta += PinAdorner_DragDelta;
			//_dicPins[PinPlacement.Output].DragDelta += PinAdorner_DragDelta;
		}


		double dx = 0.0;
		double dy = 0.0;

		/// <summary>
		/// Determine how far the pencil moved, and draw the connector line using invalidate and render
		/// </summary>
		private void PinAdorner_DragDelta(object sender, DragDeltaEventArgs e)
		{
			
			FrameworkElement elt = this.AdornedElement as FrameworkElement;
			if (elt != null)
			{
				Thumb t = sender as Thumb;
				
				if (t != null)
				{

					PinPlacement th = (PinPlacement)t.Tag;
					switch (th)
					{
						case PinPlacement.Input:
							{
								double x = 0;
								double y = 0;

								this.dx = e.HorizontalChange;
								this.dy = e.VerticalChange;
								this.InvalidateVisual();

								//	Rect adornedElementRect = new Rect(this.AdornedElement.DesiredSize);
								//	drawingContext.DrawLine(new Pen(Brushes.Blue, 1), new Point(0, 0), new Point(this.dx, this.dy));
								break;
							}
						case PinPlacement.Output:
							{

								break;
							}
						
						default:
							break;
					}
				}
			}
		}

		private Thumb CreateThumb(double width, double height, Brush color, Cursor cursor, PinPlacement whatCorner)
		{

			Thumb result = new Thumb();
			result.Width = width;
			result.Height = height;
			result.Background = color;
			result.Cursor = cursor;
			result.Tag = whatCorner;
			_children.Add(result);
			return result;
		}

		protected override void OnRender(DrawingContext drawingContext)
		{
			// draw a line from the thumb to the mouse
			Rect adornedElementRect = new Rect(this.AdornedElement.DesiredSize);
			Point p = _dicPins[PinPlacement.Input].TransformToAncestor(this).Transform(new Point(0, 0));
			drawingContext.DrawLine(new Pen(Brushes.Blue, 1), p, new Point(p.X + this.dx, p.Y + this.dy));
			base.OnRender(drawingContext);
		}

		protected override Size ArrangeOverride(Size finalSize)
		{
			// Place the input pin on the object
			_dicPins[PinPlacement.Input].Arrange(new Rect(this.DesiredSize.Width -17, 0 + 17, _dicPins[PinPlacement.Input].Width, _dicPins[PinPlacement.Input].Height));


			return finalSize;
		}


		VisualCollection _children;
		protected override int VisualChildrenCount
		{
			get
			{
				return this._children.Count;
			}
		}

		protected override Visual GetVisualChild(int index)
		{
			return this._children[index];
		}
	}
}
